package com.aspect;

import com.annotation.DistributedLock;
import com.util.RedisUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class LockCheckAspect {

    /**
     * lua
     */
    private static final String RELEASE_LOCK_LUA_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private RedisUtil redisUtil;

    // 增强带有CacheLock注解的方法
    @Pointcut("@annotation(com.annotation.DistributedLock)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        // 可以根据业务获取用户唯一的个人信息，例如手机号码
        String phone = "13823716458";

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        DistributedLock cacheLock = method.getAnnotation(DistributedLock.class);
        String prefix = cacheLock.prefix();
        if (prefix == "" || prefix == null) {
            throw new Exception("CacheLock prefix can't be null");
        }
        // 拼接 key
        String delimiter = cacheLock.delimiter();
        StringBuilder sb = new StringBuilder();
        sb.append(prefix).append(delimiter).append(phone);
        final String lockKey = sb.toString();
        final String UUID = java.util.UUID.randomUUID().toString();
        try {
            // 获取锁
            boolean success = redisTemplate.opsForValue().setIfAbsent(lockKey, UUID);

            if (success == false) {
                throw new Exception("请勿重复提交");
            }else {
                redisUtil.begin();
                redisUtil.set(lockKey,UUID, 5000);
                redisUtil.exec();
            }
            Object result = joinPoint.proceed();
            return result;
        } finally {
            // 最后记得释放锁
           // DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(RELEASE_LOCK_LUA_SCRIPT, Long.class);
            //Long result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), UUID);
        }
    }
}
